home *** CD-ROM | disk | FTP | other *** search
/ ftp.cs.arizona.edu / ftp.cs.arizona.edu.tar / ftp.cs.arizona.edu / icon / newsgrp / group94a.txt / 000015_icon-group-sender _Mon Jan 10 14:39:42 1994.msg < prev    next >
Internet Message Format  |  1994-08-19  |  7KB

  1. Received: by cheltenham.cs.arizona.edu; Mon, 17 Jan 1994 20:20:15 MST
  2. Date: 10 Jan 94 14:39:42 GMT
  3. From: mlfarm!auda!ron@uunet.uu.net  (Ronald Florence)
  4. Organization: Maple Lawn Farm, Stonington, CT
  5. Subject: envelope.icn (addresses envelopes with barcodes)
  6. Message-Id: <CJF4qB.5zD@mlfarm.com>
  7. Sender: icon-group-request@cs.arizona.edu
  8. To: icon-group@cs.arizona.edu
  9. Status: R
  10. Errors-To: icon-group-errors@cs.arizona.edu
  11.  
  12. I've missed the occasional posts of short, useful code we used to see
  13. in this newsgroup, not only as a source of utilities, but as models of
  14. good Icon coding techniques.  I'm posting this updated version of an
  15. envelope addresser I wrote several years ago in the hope that someone
  16. may find it useful, and that I may get back some suggestions of better
  17. ways to do the string scanning and other Icon coding.
  18.  
  19. We've used this addresser with both Postscript and HP-laserjet
  20. printers, for letters in groff and LaTeX, and mailing lists.
  21.  
  22. ############################################################################
  23. #
  24. #    Name:    envelope.icn
  25. #
  26. #    Title:    Envelope Addresser (with barcodes)
  27. #
  28. #    Author:    Ronald Florence (ron@mlfarm.com)
  29. #
  30. #    Date:    10 January 1994
  31. #
  32. #    Version: 1.1
  33. #
  34. ############################################################################
  35. #  
  36. #  This program addresses envelopes on a Postscript or HP-LJ printer,
  37. #  including barcodes for the zip code.  A line beginning with `#' or
  38. #  an optional alternate separator can be used to separate multiple
  39. #  addresses.  The parser will strip the formatting commands from an
  40. #  address in a troff or LaTeX letter.
  41. #
  42. #  usage: envelope [options] < address(es)
  43. #  
  44. #  Typically, envelope is used from inside an editor.  In emacs, mark
  45. #  the region of the address and do
  46. #    M-| envelope 
  47. #  In vi, put the cursor on the first line of the address and do
  48. #    :,+N w !envelope 
  49. #  where N = number-of-lines-in-address.  
  50. #
  51. #  The barcode algorithm is adapted from a perl script by Todd Merriman
  52. #  <todd@toolz.uucp>, Dave Buck <dave@dlb.uucp>, and Andy Rabagliati
  53. #  <andyr@wizzy.com>.
  54. #
  55. ############################################################################
  56. #
  57. #  Link: options
  58. #
  59. ############################################################################
  60.  
  61. link options
  62. global Printertype
  63.  
  64. procedure main(arg)
  65.   local opts, lp, separator, printerinit, printerclear, 
  66.     hpinit, hppos, xorigin, yorigin, rotate, font, 
  67.     prn, addr, psprefix, preface, optstr, usage, goodline
  68.  
  69.   usage := ["usage: envelope [options] < address(es)",
  70.         "\t-p | -postscript",
  71.         "\t-h | -hplj",
  72.         "\t-l | -printer spooler-program",
  73.         "\t-s | -separator string",
  74.         "\t-i | -init  printer-init",
  75.         "\t-c | -clear printer-clear",
  76.         "\t-f | -font fontname    [Postscript only]",
  77.         "\t-x | -xorigin xorigin  [Postscript only]",
  78.         "\t-y | -yorigin yorigin  [Postscript only]",
  79.         "\t-r | -rotate rotation  [Postscript only]",
  80.         "\t-hpinit string  [hplj only]",
  81.         "\t-hppos  string  [hplj only]" ]
  82.   psprefix := ["%! Postscript",
  83.                "/adline { 10 y moveto show /y y 13 sub def } def",
  84.                "/barcode {",
  85.                "  /y y 13 sub 0.72 div def",
  86.                "  0.72 dup scale 2 setlinewidth",
  87.                "  /x 100 def",
  88.                "  /next { x y moveto /x x 5 add def } def",
  89.                "  /S { next 0 5 rlineto stroke } def",
  90.                "  /L { next 0 12 rlineto stroke } def } def",
  91.                "/newenvelope {",
  92.                "  /y 80 def" ]
  93.   optstr := "hpl:f:r+i:c:x+y+s:?"
  94.   optstr ||:= "-help!-printer:-hpinit:-hppos:-postscript!:-font:-hplj!"
  95.   optstr ||:= "-rotate+-xorigin+-yorigin+-init:-clear:-separator:"
  96.   opts := options(arg, optstr)
  97.   \opts["?"|"help"] | arg[1] == "?" & { 
  98.     every write (!usage)
  99.     exit (-1)
  100.   }
  101.                     # change defaults below as needed
  102.   Printertype :=                 "hplj"
  103.   lp := \opts["l"|"printer"] |            "lpr"
  104.   separator := \opts["s"|"separator"] |        "#"
  105.   printerinit := \opts["i"|"init"] |              ""
  106.   printerclear := \opts["c"|"clear"] |        ""
  107.                     # the next four are Postscript-only
  108.   xorigin := \opts["x"|"xorigin"] |        200           
  109.   yorigin := \opts["y"|"yorigin"] |        400
  110.   rotate := \opts["r"|"rotate"] |        90
  111.   font := \opts["f"|"font"] |            "Palatino-Bold"
  112.                     # these two are hplj-only
  113.                     # comm. env., manual feed, landscape
  114.   hpinit := \opts["hpinit"] |            "\33&k2G\33&l81a3h1O"
  115.   hppos := \opts["hppos"] |            "\33&a40L\33*p550Y"
  116.  
  117.   \opts["h"|"hplj"] & Printertype := "hplj"
  118.   \opts["p"|"postscript"] & Printertype := "postscript"
  119.   if "pipes" == &features then prn := open(lp, "pw")
  120.   else if "MS-DOS" == &features then prn := open ("PRN", "w")
  121.   else stop ("envelope: please configure printer")
  122.   writes(prn, printerinit)
  123.  
  124.   if map(Printertype) == "postscript" then {
  125.     every write(prn, !psprefix)
  126.     write(prn, "  ", xorigin, " ", yorigin, " translate ", rotate, " rotate")
  127.     write(prn, "  /", font, " findfont 12 scalefont setfont } def")
  128.     preface := "newenvelope\n"
  129.   }
  130.   else preface := hpinit || hppos
  131.   addr := []
  132.   every !&input ? {
  133.                 # filter troff junk
  134.     =(".DE" | ".fi") & break
  135.     if =(".DS" | ".nf") then tab(0)
  136.                 # multiple addresses with separators
  137.     if =separator then {
  138.       (*addr > 0) & address(addr, prn, preface) 
  139.       addr := []
  140.       tab(0)
  141.     }
  142.                 # filter LaTeX junk
  143.     else {
  144.       if ="\\begin" then { 
  145.     every tab(upto('{')+1) \2
  146.     goodline := clean(tab(0), '\\')
  147.       }
  148.       else goodline := clean(tab(0), '\\')
  149.       put(addr, trim(goodline, ' }'))
  150.     }
  151.   }
  152.   (*addr > 0) & address(addr, prn, preface)
  153.   writes(prn, printerclear)
  154. end
  155.  
  156.  
  157. procedure address(addr, prn, preface)
  158.   local zip, zline
  159.  
  160.   zip := ""
  161.   writes(prn, preface)
  162.   every !addr ? 
  163.     if map(Printertype) == "postscript" then 
  164.       write(prn, "(", tab(0), ") adline")
  165.     else write(prn, tab(0))
  166.                 # scan for zipcode
  167.   while *(zline := trim(pull(addr))) = 0
  168.   reverse(zline) ? if many(&digits++'-') = (6|11) then
  169.       while tab(upto(&digits)) do zip ||:= tab(many(&digits))
  170.   (*zip = (5|9)) & barcode(reverse(zip), prn)
  171.   if map(Printertype) == "postscript" then write(prn, "showpage")
  172.   else writes(prn, "\33E")
  173. end
  174.  
  175.  
  176. procedure barcode(zip, prn)
  177.   local z, zipstring, cksum, bar
  178.  
  179.   cksum := 0
  180.   every cksum +:= !zip
  181.   zip := zip || (100 - cksum) % 10
  182.   bar := ["LLSSS", "SSSLL", "SSLSL", "SSLLS", "SLSSL", 
  183.       "SLSLS", "SLLSS", "LSSSL", "LSSLS", "LSLSS" ]
  184.                 # The barcode is wrapped in long marks
  185.   zipstring := "L"
  186.                 # Icon lists are indexed from 1
  187.   every z := !zip do zipstring ||:= bar[z + 1]
  188.   zipstring ||:= "L"
  189.   if map(Printertype) == "postscript" then write(prn, "barcode")
  190.   else writes(prn, "\33*p990y1575X\33*c6A")    
  191.   every !zipstring ? 
  192.     if map(Printertype) == "postscript" then write(prn, tab(0))
  193.     else {
  194.       if =("S") then writes(prn, "\33*p+21Y\33*c15b0P\33*p-21Y")
  195.       else writes(prn, "\33*c36b0P")
  196.       writes(prn, "\33*p+15X")
  197.     }
  198. end
  199.  
  200.  
  201. procedure clean(s, c)
  202.  
  203.   while i := upto(c, s) do s[i:many(c,s,i)] := ""
  204.   return s
  205. end
  206.  
  207. # ----------------------------[eof]---------------------------
  208. --
  209.  
  210.                 Ronald Florence
  211.                 ron@mlfarm.com
  212.